<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #app {
        width: 600px;
        margin: 10px auto;
      }

      .tb {
        border-collapse: collapse;
        width: 100%;
      }

      .tb th {
        background-color: #0094ff;
        color: white;
      }

      .tb td,
      .tb th {
        padding: 5px;
        border: 1px solid black;
        text-align: center;
      }

      .tb img {
        width: 100px;
        height: 100px;
      }

      .add {
        padding: 5px;
        border: 1px solid black;
        margin-bottom: 10px;
      }

      @keyframes circle-482c6307 {
        0% {
          transform: rotate(0);
        }

        to {
          transform: rotate(360deg);
        }
      }
      .loading {
        width: 30px;
        height: 30px;
        border: 2px solid #000;
        border-top-color: transparent;
        border-radius: 100%;
        animation: circle-482c6307 infinite 0.75s linear;
      }

      [v-cloak] {
        display: none;
      }

      .arrow {
        display: inline-block;
        vertical-align: middle;
        width: 0;
        height: 0;
        margin-left: 5px;
      }

      .arrow.asc {
        border-left: 4px solid transparent;
        border-right: 4px solid transparent;
        border-bottom: 4px solid #fff;
      }

      .arrow.desc {
        border-top: 4px solid #fff;
        border-left: 4px solid transparent;
        border-right: 4px solid transparent;
      }

      .red {
        color: red !important;
      }

      .red .arrow.asc {
        border-bottom: 4px solid red;
      }

      .red .arrow.desc {
        border-top: 4px solid red;
      }
    </style>
  </head>
  <body>
    <div id="app" v-cloak>
      <div>
        <label>
          <span>图片地址：</span>
          <input type="text" v-model="model.imgSrc" />
        </label>

        <label>
          <span>商品名称：</span>
          <input type="text" v-model="model.name" />
        </label>

        <label>
          <span>商品售价：</span>
          <input type="text" v-model="model.price" />
        </label>

        <button :disabled="isDisabled" @click="onAdd">新增</button>
      </div>

      <hr />

      <button :disabled="loading" @click="refresh">refresh</button>

      <hr />

      <table class="tb">
        <thead>
          <tr>
            <th>
              <input type="checkbox" name="" id="" />
            </th>
            <th>产品图片</th>
            <th>编号</th>
            <th>品牌名称</th>
            <th
              :class="{ red: sortBy === 'price' }"
              @click="handleSort('price')"
            >
              价格
              <span class="arrow" :class="orderBy.price"></span>
            </th>
            <th
              :class="{ red: sortBy === 'count' }"
              @click="handleSort('count')"
            >
              数量
              <span class="arrow" :class="orderBy.count"></span>
            </th>
            <th>操作</th>
          </tr>
        </thead>

        <tbody>
          <tr v-for="item in displayProducts" :key="item.id">
            <td>
              <input type="checkbox" name="" id="" />
            </td>
            <td>
              <img :src="item.imgSrc" alt="" />
            </td>
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>
            <td>{{ item.price }}</td>
            <td>
              <button @click="updateCount(item, 'decrement')">-</button>
              {{ item.count }}
              <button @click="updateCount(item, 'increment')">+</button>
            </td>
            <td>
              <button @click="del(item.id)">删除</button>
            </td>
          </tr>
        </tbody>
      </table>

      <div v-show="loading" class="loading"></div>
    </div>

    <script src="../../lib/vue3.js"></script>
    <script src="../../lib/axios.min.js"></script>
    <script>
      Vue.createApp({
        data() {
          return {
            loading: false, // 用于表示当前是否正在请求数据中
            products: [], // 用于存放接口调用之后的商品数据

            model: {
              imgSrc: "",
              name: "",
              price: "",
            },

            sortBy: "price", // 用于表示当前的排序字段， price | count
            orderBy: {
              price: "asc",
              count: "asc",
            },
            // order: "asc", // 用于表示当前的排序方式，asc - 升序 desc - 降序
          };
        },

        computed: {
          isDisabled() {
            return !this.model.imgSrc || !this.model.name || !this.model.price;
          },

          // 用于页面展示的商品数据
          //    依赖项： products 、orderBy、sortBy
          displayProducts() {
            // 针对 products 做一个浅拷贝，避免修改到原始数据
            return [...this.products].sort((a, b) => {
              if (this.orderBy[this.sortBy] === "asc") {
                return a[this.sortBy] - b[this.sortBy];
              } else {
                return b[this.sortBy] - a[this.sortBy];
              }
            });
          },
        },

        methods: {
          // 处理排序
          //    type - price | count
          handleSort(type) {
            // // 1. 将 order 取反
            // this.order = this.order === "asc" ? "desc" : "asc";

            // 1. 将 sortBy 赋值
            this.sortBy = type;

            // 2. 根据 type 修改 orderBy 中对应字段
            this.orderBy[type] = this.orderBy[type] === "asc" ? "desc" : "asc";
          },

          // 新增
          onAdd() {
            axios
              .post("http://localhost:3000/products", {
                ...this.model,
                // imgSrc: this.model.imgSrc,
                // name: this.model.name,
                // price: this.model.price,
                count: 1,
              })
              .then(({ data }) => {
                console.log("ok", data);

                this.products.push(data);
              });
          },

          // 刷新
          refresh() {
            this.loading = true;

            axios
              .get("http://localhost:3000/products")
              .then((response) => {
                console.log(response.data);

                // 赋值给 products
                this.products = response.data;
              })
              .finally(() => {
                // 重置 loading

                this.loading = false;
              });
          },

          // 数量添加
          increment(id, count) {
            const url = `http://localhost:3000/products/${id}`;
            axios
              .patch(url, {
                count: count + 1,
              })
              .then(() => {
                console.log("ok");
                // 1. 再调用一次 refresh 从新请求最新的数据来渲染
                //    这种方式简单，但是如果查询接口比较慢，或者对性能有要求的话，不推荐这样写
                // this.refresh();

                // 2. 针对本地 data 中 数据做修改
                //    1. 根据 当前 id 到 products 中找到要操作的 项目
                const prod = this.products.find((item) => item.id === id);
                //    2. 对找到的项目做修改
                prod.count = count + 1;
              });
          },

          updateCount(prod, type = "increment") {
            const url = `http://localhost:3000/products/${prod.id}`;
            const count =
              type === "increment" ? prod.count + 1 : prod.count - 1;

            axios
              .patch(url, {
                count: count,
              })
              .then(() => {
                console.log("ok");
                // 1. 再调用一次 refresh 从新请求最新的数据来渲染
                //    这种方式简单，但是如果查询接口比较慢，或者对性能有要求的话，不推荐这样写
                // this.refresh();

                // 2. 针对本地 data 中 数据做修改
                prod.count = count;
              });
          },

          // 删除某个商品
          del(id) {
            console.log("1111111");
            const url = `http://localhost:3000/products/${id}`;
            axios.delete(url).then(() => {
              console.log("ok");

              // 1. 直接刷新
              // this.refresh();

              // 2. 操作本地数据做移除
              this.products = this.products.filter((item) => item.id !== id);
            });
          },
        },
      }).mount("#app");
    </script>
  </body>
</html>
